package com.ruoyi.client.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.client.annotation.Client_oper;
import com.ruoyi.client.domain.entity.BlogArticle;
import com.ruoyi.client.domain.entity.BlogCollect;
import com.ruoyi.client.domain.vo.EchartsVo;
import com.ruoyi.client.eum.ClientBusinessType;
import com.ruoyi.client.mapper.BlogCollectMapper;
import com.ruoyi.client.service.IBlogArticleService;
import com.ruoyi.client.service.IBlogCollectService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.utils.SpringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 * 收藏记录 服务实现类
 * </p>
 *
 * @author fz
 * @since 2025-02-27
 */
@Service
public class BlogCollectServiceImpl extends ServiceImpl<BlogCollectMapper, BlogCollect> implements IBlogCollectService {

    @Override
    @Transactional
    public void collectArticle(BlogCollect collect, Boolean isCollect) {
        IBlogArticleService articleService = SpringUtils.getBean(IBlogArticleService.class);
        // 检查是否已经收藏
        BlogCollect one = getOne(Wrappers.<BlogCollect>lambdaQuery()
            .eq(BlogCollect::getUserId, collect.getUserId())
            .eq(BlogCollect::getTargetId, collect.getTargetId())
        );
        if (isCollect && one == null) {
            one = new BlogCollect();
            one.setUserId(collect.getUserId());
            one.setTargetId(collect.getTargetId());
            one.setTargetType(collect.getTargetType());
            one.setUrl(collect.getUrl());
            save(one);
            UpdateWrapper<BlogArticle> wrapper = new UpdateWrapper<>();
            wrapper.setSql("collect_num = collect_num + 1")
                .eq("id", collect.getTargetId());
            articleService.update(wrapper);
        }
        else{
            if (one != null){
                removeById(one);
                UpdateWrapper<BlogArticle> wrapper = new UpdateWrapper<>();
                wrapper.setSql("collect_num = collect_num - 1")
                    .eq("id", collect.getTargetId());
                articleService.update(wrapper);
            }
        }
    }
    @Override
    public List<EchartsVo> addLikeNum(Long userId, LocalDateTime startTime, LocalDateTime endTime) {
        // 查询点赞记录
        List<BlogCollect> list = list(Wrappers.<BlogCollect>lambdaQuery()
            .eq(BlogCollect::getUserId, userId)
            .between(BlogCollect::getCreateTime, startTime, endTime)
        );
        // 如果查询结果为空，直接返回空列表
        if (CollectionUtil.isEmpty(list)) {
            return generateEmptyResult(startTime.toLocalDate(), endTime.toLocalDate());
        }
        // 按日期分组统计点赞数
        Map<LocalDate, Long> detail = list.stream()
            .collect(Collectors.groupingBy(
                blogLike -> blogLike.getCreateTime().toLocalDate(),
                Collectors.counting()
            ));
        // 补全没有值的日期
        return generateResultWithMissingDates(detail, startTime.toLocalDate(), endTime.toLocalDate());
    }
    /**
     * 生成时间范围内的所有日期
     */
    private List<LocalDate> generateDateRange(LocalDate startDate, LocalDate endDate) {
        long numOfDays = ChronoUnit.DAYS.between(startDate, endDate) + 1; // 包括结束日期
        return Stream.iterate(startDate, date -> date.plusDays(1))
            .limit(numOfDays)
            .collect(Collectors.toList());
    }

    /**
     * 生成补全后的结果
     */
    private List<EchartsVo> generateResultWithMissingDates(Map<LocalDate, Long> detail, LocalDate startDate, LocalDate endDate) {
        List<EchartsVo> result = new ArrayList<>();
        List<LocalDate> dateRange = generateDateRange(startDate, endDate);

        for (LocalDate date : dateRange) {
            EchartsVo vo = new EchartsVo();
            vo.setName(date.getMonthValue() + "月" + date.getDayOfMonth() + "日");
            vo.setValue(detail.getOrDefault(date, 0L)); // 如果有值则使用，否则补全为0
            result.add(vo);
        }

        return result;
    }

    /**
     * 生成空结果（所有日期的点赞数为0）
     */
    private List<EchartsVo> generateEmptyResult(LocalDate startDate, LocalDate endDate) {
        List<EchartsVo> result = new ArrayList<>();
        List<LocalDate> dateRange = generateDateRange(startDate, endDate);

        for (LocalDate date : dateRange) {
            EchartsVo vo = new EchartsVo();
            vo.setName(date.getMonthValue() + "月" + date.getDayOfMonth() + "日");
            vo.setValue(0L); // 点赞数为0
            result.add(vo);
        }

        return result;
    }
}
